home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Documentation / develop articles / develop Issue 17 / MultipleMovies / MyMultipleMoviesApp ƒ / BetterFlattenMovie.c next >
Encoding:
Text File  |  1997-02-26  |  5.7 KB  |  198 lines  |  [TEXT/KAHL]

  1. //--------------------------------------------------------------------------
  2. //
  3. //        BetterFlattenMovie.
  4. //            by John Wang
  5. //
  6. //        Description:    Better version of FlattenMovie and FlattenMovie Data.  Also
  7. //                        includes two routines for accessing movie resource atoms in
  8. //                        the data fork  (single-fork movies).
  9. //
  10. //        Version:    1.0        11/09/93    Completed for develop column.
  11. //
  12. //--------------------------------------------------------------------------
  13.  
  14. #include    <GestaltEqu.h>
  15. #include    <Movies.h>
  16. #include    "BetterFlattenMovie.h"
  17.  
  18. //--------------------------------------------------------------------------
  19.  
  20. pascal void BetterFlattenMovie(Movie theMovie, long movieFlattenFlags, 
  21.             FSSpec *theFile, OSType creator, ScriptCode scriptTag,
  22.             long createMovieFileFlags, short *resId, const StringPtr resName)
  23. {
  24.     Movie        tempMovie;
  25.     short        refNum;
  26.     
  27.     tempMovie = BetterFlattenMovieData(theMovie, movieFlattenFlags, 
  28.             theFile, creator, scriptTag, createMovieFileFlags);
  29.  
  30.     if (tempMovie) {
  31.         if (OpenMovieFile(theFile, &refNum, fsRdWrPerm) == noErr) {
  32.             AddMovieResource( tempMovie, refNum, resId, resName);
  33.             CloseMovieFile(refNum);
  34.         }
  35.         DisposeMovie(tempMovie);
  36.     }
  37. }
  38.  
  39. pascal Movie BetterFlattenMovieData(Movie theMovie, long movieFlattenFlags, 
  40.             FSSpec *theFile, OSType creator, ScriptCode scriptTag,
  41.             long createMovieFileFlags)
  42. {
  43.     long        QTfeature;
  44.     long        readLength, writeLength, newFileSize, origFileSize;
  45.     long        origheader[2];
  46.     long        newheader[2];
  47.     Movie        tempMovie;
  48.     short        destRefNum;
  49.  
  50.     if (Gestalt(gestaltQuickTime, &QTfeature))
  51.         return(0);
  52.     
  53.     //    Do patch only if running QuickTime 1.6.X or less.
  54.     if ((QTfeature >> 16) < 0x170) {
  55.         origheader[0] = 0;
  56.         origheader[1] = 0;
  57.         //    If file exists and the file size is greater than 8, then we can
  58.         //    assume a atom header exists.  We will read this header into
  59.         //    memory so that we can restore it after calling QuickTime's
  60.         //    FlattenMovieData.
  61.         if (FSpOpenDF(theFile, fsRdPerm, &destRefNum) == noErr) {
  62.             if (GetEOF(destRefNum, &origFileSize))
  63.                 return(nil);
  64.             if (origFileSize >= 8) {
  65.                 if (SetFPos(destRefNum, fsFromStart, 0))
  66.                     return(0);
  67.                 readLength = 8;
  68.                 if (FSRead(destRefNum, &readLength, origheader))
  69.                     return(0);
  70.             }
  71.             FSClose(destRefNum);
  72.         }
  73.     }
  74.     
  75.     //    Call QuickTime's FlattenMovieData.
  76.     tempMovie = FlattenMovieData(theMovie, movieFlattenFlags, theFile, creator, scriptTag, createMovieFileFlags);
  77.  
  78.     //    Do patch only if running QuickTime 1.6.X or less.
  79.     if ((QTfeature >> 16) < 0x170) {
  80.         if (FSpOpenDF(theFile, fsWrPerm, &destRefNum) == noErr) {
  81.             //    Get new header which is always stored at offset 0 of data fork.
  82.             newheader[0] = 0;
  83.             newheader[1] = 0;
  84.             if (GetEOF(destRefNum, &newFileSize))
  85.                 return(0);
  86.             if (newFileSize >= 8) {
  87.                 if (SetFPos(destRefNum, fsFromStart, 0))
  88.                     return(0);
  89.                 readLength = 8;
  90.                 if (FSRead(destRefNum, &readLength, newheader))
  91.                     return(0);
  92.             }
  93.             
  94.             //    Write old header back.
  95.             if (newFileSize >= 8) {
  96.                 if (SetFPos(destRefNum, fsFromStart, 0))
  97.                     return(0);
  98.                 writeLength = 8;
  99.                 if (FSWrite(destRefNum, &writeLength, origheader))
  100.                     return(0);
  101.             }
  102.             
  103.             //    Write new header in the right place.
  104.             if (newFileSize > (origFileSize + 8)) {
  105.                 if (SetFPos(destRefNum, fsFromStart, origFileSize))
  106.                     return;
  107.                 //    If newheader size is not 0, then calculate new header size by
  108.                 //        (i) subtracting out the original file size if the newheader size is
  109.                 //            larger than the original file size.
  110.                 //        (ii) subtracting the original filesize fromt the new filesize if
  111.                 //            the header size is less than or equal to the original filesize.
  112.                 //            The reason for this is that FlattenMovieData does not calculate
  113.                 //            a new header size unless the movie atom is written to the data fork.
  114.                 //            Thus, if there is no data fork, then we can assume that the only
  115.                 //            atom added is the movie data atom.
  116.                 //    If newheader size is equal to 0, then probably there is no movie
  117.                 //    atom and the size is simply the size to the end of the file.
  118.                 if (newheader[0] != 0) {
  119.                     if (newheader[0] <= origFileSize)
  120.                         newheader[0] = newFileSize - origFileSize;
  121.                     else
  122.                         newheader[0] = newheader[0] - origFileSize;
  123.                 }  else
  124.                     newheader[0] = newFileSize - origFileSize;
  125.                 writeLength = 8;
  126.                 if (FSWrite(destRefNum, &writeLength, newheader))
  127.                     return;
  128.             }
  129.             FlushVol(nil, theFile->vRefNum);
  130.             FSClose(destRefNum);
  131.         }
  132.     }
  133.     
  134.     return(tempMovie);
  135. }
  136.  
  137. //--------------------------------------------------------------------------
  138.  
  139. OSErr CountMoviesInDataFork(FSSpec *theFile, short *count)
  140. {
  141.     long        header[2];
  142.     short        myRefNum;
  143.     long        fileSize, currentLoc, readLength;
  144.     short        doneCounter;
  145.     OSErr        err;
  146.  
  147.     *count = 0;
  148.     if (FSpOpenDF(theFile, fsRdPerm, &myRefNum) == noErr) {
  149.         if (err = GetEOF(myRefNum, &fileSize))
  150.             return(err);
  151.         currentLoc = 0;
  152.         doneCounter = 0;
  153.         while (fileSize > (currentLoc + 8)) {
  154.             if (err = SetFPos(myRefNum, fsFromStart, currentLoc))
  155.                 return(err);
  156.             readLength = 8;
  157.             if (err = FSRead(myRefNum, &readLength, header))
  158.                 return(err);
  159.             if (header[1] == 'moov')
  160.                 doneCounter++;
  161.             currentLoc += header[0];
  162.         }
  163.         *count = doneCounter;
  164.         FSClose(myRefNum);
  165.     } else
  166.         return(err);
  167.     return(noErr);
  168. }
  169.  
  170. OSErr SearchMoviesInDataFork(FSSpec *theFile, short index, long *fileOffset)
  171. {
  172.     long        header[2];
  173.     short        myRefNum;
  174.     long        currentLoc, readLength;
  175.     short        doneCounter;
  176.     OSErr        err;
  177.  
  178.     if (FSpOpenDF(theFile, fsRdPerm, &myRefNum) == noErr) {
  179.         currentLoc = 0;
  180.         doneCounter = index;
  181.         *fileOffset = 0;
  182.         while ((doneCounter > 0)) {
  183.             if (err = SetFPos(myRefNum, fsFromStart, currentLoc))
  184.                 return(err);
  185.             readLength = 8;
  186.             if (err = FSRead(myRefNum, &readLength, header))
  187.                 return(err);
  188.             if (header[1] == 'moov')
  189.                 doneCounter--;
  190.             *fileOffset = currentLoc;
  191.             currentLoc += header[0];
  192.         }
  193.         FSClose(myRefNum);
  194.     } else
  195.         return(err);
  196.     return(noErr);
  197. }
  198.